home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / Splitter.C < prev    next >
C/C++ Source or Header  |  1990-12-04  |  5KB  |  216 lines

  1. //$Splitter,SplitScroller,SplitBar$
  2. #include "Splitter.h"
  3. #include "Scroller.h"
  4.  
  5. const int cSplitGap= 3;
  6.  
  7. //---- SplitBar ----------------------------------------------------------------
  8.  
  9. class SplitBar: public VObject {
  10.     Splitter *splitframe;
  11.     bool vertical;
  12. public:
  13.     MetaDef(SplitBar);
  14.     SplitBar(Splitter *sf, bool v, int w, int h) : VObject(Point(w, h), cIdNone)
  15.     { splitframe= sf; vertical= v; }
  16.     void DrawInner(Rectangle r, bool feedback)
  17.     { if (!feedback) GrPaintRect(r, ePatBlack); }
  18.     Command *DoLeftButtonDownCommand(Point, Token, int);
  19.     void SetOrigin(Point at);
  20. };
  21.  
  22. MetaImpl(SplitBar, (TP(splitframe), TB(vertical), 0));
  23.  
  24. Command *SplitBar::DoLeftButtonDownCommand(Point, Token, int clicks)
  25. {
  26.     if (clicks >= 2) {
  27.     splitframe->SetSplit(vertical, Point(cSplitGap));
  28.     return gNoChanges;
  29.     }
  30.     Rectangle constrainRect(splitframe->contentRect);
  31.     if (vertical) {
  32.     constrainRect.origin.x+= constrainRect.extent.x-Width();
  33.     constrainRect.extent.x= Width();
  34.     } else {
  35.     constrainRect.origin.y+= constrainRect.extent.y-Height();
  36.     constrainRect.extent.y= Height();
  37.     }
  38.     Command *cmd= new VObjectMover(this, constrainRect);
  39.     cmd->ResetFlag(eCmdCanUndo);
  40.     return cmd;
  41. }
  42.  
  43. void SplitBar::SetOrigin(Point at)
  44. {
  45.     VObject::SetOrigin(at);
  46.     splitframe->SetSplit(vertical, at);
  47. }
  48.  
  49. //---- SplitScroller -----------------------------------------------------------
  50.  
  51. class SplitScroller: public Scroller {
  52. public:
  53.     MetaDef(SplitScroller);
  54.     SplitScroller(VObject *v, Point ms, int id, ScrollDir sd)
  55.                             : Scroller(v, ms, id, sd)
  56.     { }
  57.     void Control(int, int part, void *vp);
  58. };
  59.  
  60. MetaImpl0(SplitScroller);
  61.  
  62. void SplitScroller::Control(int id, int part, void *vp)
  63. {
  64.     if (part == cPartViewSize)
  65.     Scroller::Control(id, part, vp);
  66.     else
  67.     VObject::Control(GetId(), part, vp);
  68. }
  69.  
  70. //---- Splitter ----------------------------------------------------------------
  71.  
  72. MetaImpl(Splitter, (T(split), T(ms), TP(vop), 0));
  73.  
  74. Splitter::Splitter(VObject *v, Point p, int id)
  75.                     : CompositeVObject(id, (Collection*)0)
  76. {
  77.     vop= v;
  78.     ms= p;
  79.     Init(v, ms);
  80.     ResetFlag(eVObjOpen);
  81. }
  82.  
  83. void Splitter::Init(VObject *v, Point p)
  84. {
  85.     split= Point(-cSplitGap);
  86.     for (int i= 0; i < 4; i++)
  87.     Add(new SplitScroller(v, p, i, ScrollDir(i)));
  88.     Add(new SplitBar(this, FALSE, cSplitGap, cScrollBarSize));
  89.     Add(new SplitBar(this, TRUE, cScrollBarSize, cSplitGap));
  90. }
  91.  
  92. void Splitter::Open(bool mode)
  93. {
  94.     VObject::Open(mode);
  95.     At(3)->Open(mode);  // right/bottom Scroller is always open
  96. }
  97.  
  98. void Splitter::SendDown(int id , int part, void *val)
  99. {
  100.     At(3)->SendDown(id, part, val); 
  101. }
  102.  
  103. void Splitter::Control(int id, int part, void *val)
  104. {
  105.     if (id >= 0 && id < 4) {
  106.     if (part != cPartScrollPos) {
  107.         VObject *v0= At(0), *v1= At(1), *v2= At(2), *v3= At(3);
  108.         Point px, py;
  109.         px= py= *(Point*)val;
  110.         if (id < 2)
  111.         py.y= px.x= 0;
  112.         else
  113.         py.x= px.y= 0;
  114.         if (id == 1 || id == 2) {
  115.         if (v0->IsOpen())
  116.             ((Scroller*)v0)->Scroller::Control(id, part, &px);
  117.         if (v3->IsOpen())
  118.             ((Scroller*)v3)->Scroller::Control(id, part, &py);
  119.         }
  120.         if (id == 0 || id == 3) {
  121.         if (v1->IsOpen())
  122.             ((Scroller*)v1)->Scroller::Control(id, part, &px);
  123.         if (v2->IsOpen())
  124.             ((Scroller*)v2)->Scroller::Control(id, part, &py);
  125.         }
  126.     }
  127.     VObject *v= At(id);
  128.     ((Scroller*)v)->Scroller::Control(id, part, val);
  129.     } else
  130.     VObject::Control(id, part, val);
  131. }
  132.  
  133. Metric Splitter::GetMinSize()
  134. {
  135.     return At(3)->GetMinSize();
  136. }
  137.  
  138. void Splitter::TestOpen(int i, int w, int h, Point &minsize)
  139. {
  140.     Point e(w,h);
  141.     register VObject *scr= At(i);
  142.     if (e >= minsize) {
  143.     if (! scr->IsOpen())
  144.         scr->Open();
  145.     scr->SetExtent(e);
  146.     } else if (scr->IsOpen())
  147.     scr->Close();
  148. }
  149.  
  150. void Splitter::SetExtent(Point e)
  151. {
  152.     Point minsize= GetMinSize().Extent();
  153.     VObject::SetExtent(e);
  154.     
  155.     TestOpen(0, split.x, split.y, minsize);
  156.     TestOpen(1, e.x-split.x-cSplitGap, split.y, minsize);
  157.     TestOpen(2, split.x, e.y-split.y-cSplitGap, minsize);
  158.     At(3)->SetExtent(Point(e.x-split.x-cSplitGap, e.y-split.y-cSplitGap));
  159. }
  160.  
  161. void Splitter::SetOrigin(Point at)
  162. {
  163.     Point p, e= GetExtent();
  164.     
  165.     VObject::SetOrigin(at);
  166.     if (At(0)->IsOpen())
  167.     At(0)->SetOrigin(at);
  168.     if (At(1)->IsOpen())
  169.     At(1)->SetOrigin(at+Point(split.x+cSplitGap, 0));
  170.     if (At(2)->IsOpen())
  171.     At(2)->SetOrigin(at+Point(0, split.y+cSplitGap));
  172.     if (At(3)->IsOpen())
  173.     At(3)->SetOrigin(at+Point(split.x+cSplitGap, split.y+cSplitGap));
  174.     p= Point(split.x<0 ? e.x-cScrollBarSize : split.x, e.y-cScrollBarSize);
  175.     At(4)->SetOrigin(at+p);
  176.     p= Point(e.x-cScrollBarSize, split.y<0 ? e.y-cScrollBarSize : split.y);
  177.     At(5)->SetOrigin(at+p);
  178. }
  179.  
  180. void Splitter::SetSplit(bool vertical, Point at)
  181. {
  182.     Point minSize= GetMinSize().Extent(), e= GetExtent();
  183.     at-= GetOrigin();
  184.     
  185.     if (vertical) {
  186.     if (at.y < minSize.y || at.y > e.y - minSize.y)
  187.         at.y= -cSplitGap;
  188.     } else {
  189.     if (at.x < minSize.x || at.x > e.x - minSize.x)
  190.         at.x= -cSplitGap;
  191.     }
  192.     
  193.     if (split[vertical] != at[vertical]) {
  194.     split[vertical]= at[vertical];
  195.     ForceRedraw();
  196.     SetExtent(contentRect.extent);
  197.     SetOrigin(contentRect.origin);
  198.     }
  199. }
  200.  
  201. ostream& Splitter::PrintOn(ostream &s)
  202. {
  203.     VObject::PrintOn(s);
  204.     return s << vop SP << ms SP;
  205. }
  206.  
  207. istream& Splitter::ReadFrom(istream &s)
  208. {
  209.     VObject::ReadFrom(s);
  210.     FreeAll();
  211.     s >> vop >> ms;
  212.     Init(vop, ms);
  213.     SetExtent(GetExtent());
  214.     return s;
  215. }
  216.